import { getViewer } from './ViewerCache'
const Cesium = window.Cesium;
/**
 * 生成UUID
 *
 * @export
 * @return {String} uuid
 */
export function uuid() {
    var uuid = '';
    for (var i = 1; i <= 32; i++) {
        var n = Math.floor(Math.random() * 16.0).toString(16);
        uuid += n;
    }
    return uuid;
};


/**
 * 获取地图选鼠标点选信息
 *
 * @export
 * @param {String} id viewer的唯一标识
 * @param {*} event 鼠标格式化信息
 * @return {*} 返回地图选取信息
 */
export function formatPostionForEvent(id, event) {
    var viewer = getViewer(id);
    let position = event.position ? event.position : event.endPosition;
    let ellipsoid = viewer.scene.globe.ellipsoid;
    var cartesian = viewer.camera.pickEllipsoid(position, ellipsoid);
    if (cartesian) {
        var cartographic = ellipsoid.cartesianToCartographic(cartesian);
        //经度
        event.latitude = Cesium.Math.toDegrees(cartographic.latitude);
        //纬度
        event.longitude = Cesium.Math.toDegrees(cartographic.longitude);
        //高度
        event.height = viewer.camera.positionCartographic.height / 1000;
        event.cartesian = cartesian;
        return event;
    } else {
        return false;
    }
}


/**
 * 获取camera中心点坐标
 *
 * @param {*} id
 * @return {*} 
 */
function getCenterPosition(id) {
    var viewer = getViewer(id);
    var result = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2));
    if (result) {
        var curPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(result);
        var lon = curPosition.longitude * 180 / Math.PI;
        var lat = curPosition.latitude * 180 / Math.PI;
        return {
            lon: lon,
            lat: lat,
        };
    } else {
        return {
            lon: null,
            lat: null,
        }
    }

}

export {
    getCenterPosition
}

/**
 * 获取当前地图镜头范围
 *
 * @param {String} id viewer的唯一标识
 * @return {Object} 范围信息 
 */
export function getCurrentExtent(id) {
    var viewer = getViewer(id);
    // 范围对象
    var extent = {};

    // 得到当前三维场景
    var scene = viewer.scene;

    // 得到当前三维场景的椭球体
    var ellipsoid = scene.globe.ellipsoid;
    var canvas = scene.canvas;

    // canvas左上角
    var car3_lt = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, 0), ellipsoid);

    // canvas右下角
    var car3_rb = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(canvas.width, canvas.height), ellipsoid);

    // 当canvas左上角和右下角全部在椭球体上
    if (car3_lt && car3_rb) {
        var carto_lt = ellipsoid.cartesianToCartographic(car3_lt);
        var carto_rb = ellipsoid.cartesianToCartographic(car3_rb);
        extent.xmin = Cesium.Math.toDegrees(carto_lt.longitude);
        extent.ymax = Cesium.Math.toDegrees(carto_lt.latitude);
        extent.xmax = Cesium.Math.toDegrees(carto_rb.longitude);
        extent.ymin = Cesium.Math.toDegrees(carto_rb.latitude);
    }

    // 当canvas左上角不在但右下角在椭球体上
    else if (!car3_lt && car3_rb) {
        var car3_lt2 = null;
        var yIndex = 0;
        do {
            // 这里每次10像素递加，一是10像素相差不大，二是为了提高程序运行效率
            yIndex <= canvas.height ? yIndex += 10 : canvas.height;
            car3_lt2 = viewer.camera.pickEllipsoid(new Cesium.Cartesian2(0, yIndex), ellipsoid);
        } while (!car3_lt2);
        var carto_lt2 = ellipsoid.cartesianToCartographic(car3_lt2);
        var carto_rb2 = ellipsoid.cartesianToCartographic(car3_rb);
        extent.xmin = Cesium.Math.toDegrees(carto_lt2.longitude);
        extent.ymax = Cesium.Math.toDegrees(carto_lt2.latitude);
        extent.xmax = Cesium.Math.toDegrees(carto_rb2.longitude);
        extent.ymin = Cesium.Math.toDegrees(carto_rb2.latitude);
    }

    var OBJ = getCenterPosition(id);
    extent.Centerlon = OBJ.lon;
    extent.Centerlat = OBJ.lat;

    // 获取高度
    extent.height = Math.ceil(viewer.camera.positionCartographic.height);
    return extent;
}

/**
 * 从经纬度获取地图 X,Y 轴坐标
 *
 * @export
 * @param {Object} geometry 经纬度对象（longitude / latitude）
 * @param {String} id viewer的唯一标识
 * @return {Object} {x:number, y:number}
 */
export function getWindowCoordinates(geometry, id) {
    var viewer = getViewer(id);
    var position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, Cesium.Cartesian3.fromDegrees(geometry.longitude, geometry.latitude));
    return position;
}

/**
 *
 *
 * @export
 * @param {Number} val 经度 / 纬度
 * @return {String} 弧度值 
 */
export function ToDegrees(val) {
    if (typeof (val) == "undefined" || val == "") {
        return "";
    }
    var i = (val + '').indexOf('.');
    var strDu = i < 0 ? val : val.substring(0, i);//获取度
    var strFen = 0;
    var strMiao = 0;
    if (i > 0) {
        var strFen = "0" + val.substring(i);
        strFen = strFen * 60 + "";
        i = strFen.indexOf('.');
        if (i > 0) {
            strMiao = "0" + strFen.substring(i);
            strFen = strFen.substring(0, i);//获取分
            strMiao = strMiao * 60 + "";
            i = strMiao.indexOf('.');
            strMiao = strMiao.substring(0, i + 4);//取到小数点后面三位
            strMiao = parseFloat(strMiao).toFixed(3);//精确小数点后面两位
        }
    }
    return strDu + "° " + strFen + "′ " + strMiao + '″';
}

/**
 * 经纬度坐标信息
 *
 * @param {Object} Position 经纬度坐标信息
 * @return {Cesium.Cartesian3} 地图的 Cartesian3 类型坐标
 */
const CreatePosition = function (Position) {
    return new Cesium.Cartesian3.fromDegrees(Position.longitude, Position.latitude, Position.height || 5000)
}

/**
 * 扇形多边形计算公式
 *
 * @export
 * @param {Number} lon 中心点经度
 * @param {Number} lat 中心点纬度
 * @param {Number} radius 扇形半径
 * @param {Number} starAngle 起始角度
 * @param {Number} endAngle 结束角度
 * @return {Array} 扇形多边形点集合 
 */
export function computeCirclularFlight(lon, lat, radius, starAngle, endAngle) {
    let Ea = 6378137; //   赤道半径
    let Eb = 6356725; // 极半径
    let positionArr = [];
    positionArr.push(CreatePosition({
        longitude: lon,
        latitude: lat
    }));
    //需求正北是0° cesium正东是0°
    for (let i = starAngle; i <= endAngle; i++) {
        let dx = radius * Math.sin((i * Math.PI) / 180.0);
        let dy = radius * Math.cos((i * Math.PI) / 180.0);
        let ec = Eb + ((Ea - Eb) * (90.0 - lat)) / 90.0;
        let ed = ec * Math.cos((lat * Math.PI) / 180);
        let BJD = lon + ((dx / ed) * 180.0) / Math.PI;
        let BWD = lat + ((dy / ec) * 180.0) / Math.PI;
        positionArr.push(CreatePosition({
            longitude: BJD,
            latitude: BWD
        }));
    }
    return positionArr;
}


/**
 * 创建环形多边形
 *
 * @export
 * @param {Number} lon 中心点经度
 * @param {Number} lat 中心点纬度
 * @param {Number} InsideRadius 内半径
 * @param {Number} OutsideRadius 外半径
 * @return {Array} 环形多边形坐标点集合
 */
export function computeAnnulusFlight(lon, lat, InsideRadius, OutsideRadius) {
    var Outside = computeCirclularFlight(lon, lat, OutsideRadius, 0, 360);
    var Inside = computeCirclularFlight(lon, lat, InsideRadius, 0, 360);

    Outside.shift()
    Inside.shift()
    // Outside.pop()
    // Inside.pop()




    return [].concat(Outside, Inside.reverse());
}

/**
 * 生成曲线来表达国家间的人口流动曲线
 * @param startPoint 起点
 * @param endPoint 终点
 * @returns {Array}
 */
export function generateCurve(startPoint, endPoint) {
    let addPointCartesian = new Cesium.Cartesian3();
    Cesium.Cartesian3.add(startPoint, endPoint, addPointCartesian);
    let midPointCartesian = new Cesium.Cartesian3();
    Cesium.Cartesian3.divideByScalar(addPointCartesian, 2, midPointCartesian);
    let midPointCartographic = Cesium.Cartographic.fromCartesian(midPointCartesian);
    midPointCartographic.height = Cesium.Cartesian3.distance(startPoint, endPoint) / 10;
    let midPoint = new Cesium.Cartesian3();
    Cesium.Ellipsoid.WGS84.cartographicToCartesian(midPointCartographic, midPoint);
    let spline = new Cesium.CatmullRomSpline({
        times: [0.0, 0.5, 1.0],
        points: [startPoint, midPoint, endPoint]
    });
    let curvePointsArr = [];
    for (let i = 0, len = 30; i < len; i++) {
        curvePointsArr.push(spline.evaluate(i / len));
    }
    return curvePointsArr;
}